/*    
    LogParser - Log File Parser
    Copyright (C) 2007  Alois Kraus
  
    This source code is published under the Microsoft Permissive License (Ms-PL)
    http://www.microsoft.com/resources/sharedsource/licensingbasics/permissivelicense.mspx
*/


using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Practices.EnterpriseLibrary.Logging;
using System.IO;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;

namespace EntLibContrib.Logging.Parser
{
    /// <summary>
    /// This class is responsibe for reading filtered LogEntry objects from a normal text file which has previously
    /// been writtern by the Enterprise Library Logging Application Block. 
    /// You can use this class to read a text file which was written by the Rolling/File Sink which did use a TextFormatter
    /// which format can be arbitrary. 
    /// </summary>
    public class FilteredLogFileReader : IEnumerable<LogEntry>
    {
        string myFileName;
        Tokenizer myTokenizer;

        /// <summary>
        /// Initializes a new instance of the <see cref="FilteredLogFileReader"/> class.
        /// </summary>
        /// <param name="logFileName">Name of the log file.</param>
        /// <param name="entlibLogCfgFile">The entlib log CFG file.</param>
        public FilteredLogFileReader(string logFileName, string entlibLogCfgFile)
            : this(logFileName, new FileConfigurationSource(entlibLogCfgFile), null)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="FilteredLogFileReader"/> class.
        /// </summary>
        /// <param name="logFileName">Name of the log file.</param>
        /// <param name="entlibLogCfgFile">The entlib log CFG file.</param>
        /// <param name="theTimeStampParser">The time stamp parser to use</param>
        public FilteredLogFileReader(string logFileName, string entlibLogCfgFile, ITimeStampParser theTimeStampParser)
            : this(logFileName, new FileConfigurationSource(entlibLogCfgFile), theTimeStampParser)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="FilteredLogFileReader"/> class.
        /// </summary>
        /// <param name="logFileName">Name of the log file.</param>
        /// <param name="entLibLogConfig">The ent lib log config.</param>
        public FilteredLogFileReader(string logFileName, IConfigurationSource entLibLogConfig)
            : this(logFileName, entLibLogConfig, null)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="FilteredLogFileReader"/> class.
        /// </summary>
        /// <param name="logFileName">Name of the log file.</param>
        /// <param name="entLibLogConfig">The ent lib log config.</param>
        /// <param name="theTimeStampParser">The time stamp parser to use</param>
        public FilteredLogFileReader(string logFileName, IConfigurationSource entLibLogConfig, ITimeStampParser theTimeStampParser)
        {
            if (String.IsNullOrEmpty(logFileName))
                throw new ArgumentException("file argument is null or empty");

            if (entLibLogConfig == null)
                throw new ArgumentNullException("entLibLogConfig");

            myFileName = logFileName;

            RegularExpressionBuilder builder = new RegularExpressionBuilder(entLibLogConfig);
            if (theTimeStampParser != null)
                myTokenizer = new Tokenizer(builder, theTimeStampParser);
            else
                myTokenizer = new Tokenizer(builder);
        }

        /// <summary>
        /// Parses the log file.
        /// </summary>
        /// <param name="filter">The filter.</param>
        /// <returns></returns>
        public IEnumerable<LogEntry> ParseLogFile(Filter filter)
        {
            string logFile = FileIO.ReadAllText(myFileName);

            foreach (LogEntry ent in myTokenizer.GetDeseralizedLogEntries(logFile, myFileName))
            {
                if( filter.Match(ent) )
                    yield return ent;
            }
        }

        #region IEnumerable<LogEntry> Members

        /// <summary>
        /// Gets the enumerator.
        /// </summary>
        /// <returns></returns>
        public IEnumerator<LogEntry> GetEnumerator()
        {
            string logFile = FileIO.ReadAllText(myFileName);

            foreach (LogEntry ent in myTokenizer.GetDeseralizedLogEntries(logFile, myFileName))
            {
                yield return ent;
            }
        }

        #endregion

        #region IEnumerable Members

        /// <summary>
        /// Gets the enumerator.
        /// </summary>
        /// <returns></returns>
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }

        #endregion
    }
}
